#include <cassert>
#include <iostream>
#include <vector>
#include "vector.h"
#include "VectorWithoutAllocator.h"
#include "BigVector.h"
#include "BigVectorWithoutAllocator.h"
#include "ObjectTest.h"
#include "MemoryPoolUnitTest.h"

namespace {
	const size_t iterations = 10000;
}

void init() {
	std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield );
	std::cout.precision( 8 );
}

void printResult(std::vector<size_t> iterations, std::vector<double> values) {
	size_t size = iterations.size();
	double average = 0.0;
	for( size_t row = 0; row < size; row++ ) {
		average += values[row];
		std::cout << iterations[row] << "\t" << values[row] << std::endl;
	}
	average /= size;
	std::cout << "Average: " << average << std::endl;
}

void testSmallObjects() {
	std::cout << "testing allocator with object size = " << sizeof( Vector ) << std::endl;
	std::vector<size_t> iterations;
	std::vector<double> values;

	for( size_t objectCount = 100; objectCount < 10000; objectCount += 100 ) {
		double ownManagerRes = ObjectTest::test<Vector>(objectCount);
		double standartManagerRes = ObjectTest::test<VectorVithoutAllocator>(objectCount);
		double result = standartManagerRes / ownManagerRes;
		iterations.push_back(objectCount);
		values.push_back(result);
	}
	
	printResult(iterations, values);
}

void testBigObjects() {
	std::cout << "testing allocator with object size = " << sizeof( BigVector ) << std::endl;
	std::vector<size_t> iterations;
	std::vector<double> values;

	for( size_t objectCount = 100; objectCount < 10000; objectCount += 100 ) {
		double ownManagerRes = ObjectTest::test<BigVector>(objectCount);
		double standartManagerRes = ObjectTest::test<BigVectorVithoutAllocator>(objectCount);
		double result = standartManagerRes / ownManagerRes;
		iterations.push_back(objectCount);
		values.push_back(result);
	}
	
	printResult(iterations, values);
}


void unitTests() {
	MemoryPoolUnitTest::correctAllocateNumberTest();
	MemoryPoolUnitTest::correctLiveObjectTest();
}

void speedTest() {
	testSmallObjects();
	std::cout << std::endl;
	testBigObjects();
}

int main()
{
	init();
	//unitTests();
	speedTest();

	return 0;
}